using System;
using System.Collections.Generic;
using System.Linq;

namespace Sherwood.Content
{
    ///<summary>
    /// Represents a repository that provides access to metas.
    ///</summary>
    public interface IMetaRepository
    {
        /// <summary>
        /// Get meta based on global unique id.
        /// </summary>
        /// <param name="id">The unique id of the meta to receive</param>
        /// <returns>Returns the meta instance with the given id if it exists and null if meta does not exist</returns>
        IMeta this[Guid id] { get; }

        /// <summary>
        /// Query all metas in system
        /// </summary>
        IQueryable<IMeta> All { get; }

        /// <summary>
        /// Get all record metas
        /// </summary>
        /// <param name="recordId">The id of the record</param>
        /// <returns>All metas belonging to specified record</returns>
        IQueryable<IMeta> GetMetas(Guid recordId);

        /// <summary>
        /// Get all record metas belonging to a specific client
        /// </summary>
        /// <param name="recordId">The id of the record</param>
        /// <param name="clientId">The id of the client</param>
        /// <returns>All metas belonging to specified record and client</returns>
        IQueryable<IMeta> GetMetas(Guid recordId, string clientId);

        /// <summary>
        /// Get a specific meta
        /// </summary>
        /// <param name="recordId">The id of the record</param>
        /// <param name="clientId">The id of the client</param>
        /// <param name="usageKey">The foreign id of the meta</param>
        /// <returns>The requested meta instance or null if not found</returns>
        T GetMeta<T>(Guid recordId, string clientId, string usageKey) where T : IMeta;

        /// <summary>
        /// Create a new meta
        /// </summary>
        /// <param name="recordId">The id of the record</param>
        /// <param name="clientId">The id of the client</param>
        /// <param name="usageKey">The foreign id of the meta</param>
        /// <returns>The newly created meta instance</returns>
        T CreateNew<T>(Guid recordId, string clientId, string usageKey) where T : IMeta, new();
        
        /// <summary>
        /// Create a new meta
        /// </summary>
        /// <param name="record">The record</param>
        /// <param name="client">The client</param>
        /// <param name="usageKey">The foreign id of the meta</param>
        /// <returns>The newly created meta instance</returns>
        T CreateNew<T>(IRecord record, IClient client, string usageKey) where T : IMeta, new();

        /// <summary>
        /// Delete the meta specified
        /// </summary>
        /// <param name="meta">The meta to delete</param>
        void Delete(IMeta meta);
    }
}